﻿namespace groopServer.Common {
    using System;
    using System.Collections.Generic;
    using Castle.Core;
    using Castle.Windsor;
    using Castle.Windsor.Configuration.Interpreters;

    public class IoC {
        public const string WindsorConfigFilename = @"windsor.config";
        private static readonly object _lockDummy = new object();
        private static IWindsorContainer _container;

        private static bool _initiliazed;

        private static void EnsureInitialized() {
            if (_initiliazed) return;

            lock (_lockDummy) {
                if (_initiliazed) return;

                string configPath = ConfigFileFinder.GetConfigFilePath("windsor", WindsorConfigFilename);
                var configInterpreter = new XmlInterpreter(configPath);

                InitializeWith(new WindsorContainer(configInterpreter));
                _initiliazed = true;
            }
        }

        public static void InitializeWith(IWindsorContainer container) {
            _container = container;
            _initiliazed = true;
        }

        public static T Resolve<T>() {
            EnsureInitialized();
            return _container.Resolve<T>();
        }

        public static T Resolve<T>(string key) {
            EnsureInitialized();
            return _container.Resolve<T>(key);
        }

        public static List<T> ResolveServices<T>() {
            EnsureInitialized();

            T[] services = _container.Kernel.ResolveServices<T>();
            return new List<T>(services);
        }

        public static void Register<Interface, Implementation>() {
            EnsureInitialized();
            Register<Interface, Implementation>(typeof(Interface).Name);
        }

        public static void Register<Interface, Implementation>(string key) {
            EnsureInitialized();
            _container.AddComponent(key, typeof(Interface), typeof(Implementation));
        }

        public static void Register(string key, Type type, LifestyleType lifestyleType) {
            EnsureInitialized();
            _container.AddComponentWithLifestyle(key, type, lifestyleType);
        }

        public static IWindsorContainer GetContainer() {
            EnsureInitialized();
            return _container;
        }

        public static void Reset() {
            if (_container == null) return;

            _container.Dispose();
            _container = null;
        }
    }
}